module GYLite
{
	export class PositionUtil
	{
		private static _pt:egret.Point=new egret.Point;
		public constructor()
		{
		}
		/**求过点cx,cy的直线在直线l(ax,ay,bx,by)上的垂点
		 * @return 垂点坐标
		 * */
		public static verticalPoint(ax:number,ay:number,bx:number,by:number,cx:number,cy:number):egret.Point
		{
			let abx:number = bx - ax;
			let aby:number = by - ay;
			let acx:number = cx - ax;
			let acy:number = cy - ay;
			if(abx == 0 && aby == 0)return null;
			let f:number = (abx*acx+aby*acy)/(abx*abx+aby*aby);  // 注意ab必须是直线上的两个不同点
			PositionUtil._pt.x = ax + f*abx;
			PositionUtil._pt.y = ay + f*aby;
			return PositionUtil._pt;
		}
		/**判断3个点是顺时针，逆时针，还是在一条直线上面
		 * @return 小于0 逆时针 大于0 顺时针 等于0 直线
		 * */
		public static clockwise(x1 :number,y1 :number,x2 :number,y2 :number,x3 :number,y3 :number) :number
		{
			return (x2-x1)*(y3-y2)-(y2-y1)*(x3-x2);
		}		
		/**判断路径是顺时针，逆时针，还是在一条直线上面
		 * @return 1逆时针 -1顺时针 0直线 2无序
		 * */
		public static clockwisePath(pathArr:Array<any>) :number
		{
			var i :number,len :number;
			var val :number;
			var result :number,result2 :number;
			len = pathArr.length;
			if(len < 6)
			{
				return 2;
			}
			val = PositionUtil.clockwise(pathArr[0],pathArr[1],pathArr[2],pathArr[3],pathArr[4],pathArr[5]);
			result = val>0?1:(val < 0?-1:0);
			for(i=6;i<len;i+=2)
			{
				val = PositionUtil.clockwise(pathArr[i-4],pathArr[i-3],pathArr[i-2],pathArr[i-1],pathArr[i],pathArr[i+1]);
				result2 = val>0?1:(val < 0?-1:0);
				if(result2 == 0)
					continue;
				if(result2 != result)
				{
					if(result == 0)
						result = result2;
					else
						return 2;
				}
			}
			return result;
		}
		/**计算路径转过的角度
		 * @return 路径转过的角度
		 * */
		public static anglePath(pathArr:Array<any>) :number
		{
			var i :number,len :number;
			var agl1 :number,agl2 :number,agl :number;
			len = pathArr.length;
			if(len < 4)
			{
				return 0;
			}
			agl = 0;
			agl1 = PositionUtil.calculateAngle(pathArr[0],pathArr[1],pathArr[2],pathArr[3]);
			if(agl1 < 0)agl1+=MathConst.DOUBLE_PI;
			agl2 = PositionUtil.calculateAngle(pathArr[pathArr.length-4],pathArr[pathArr.length - 3],pathArr[pathArr.length - 2],pathArr[pathArr.length-1]);
			if(agl2 < 0)agl2+=MathConst.DOUBLE_PI;
			agl += agl2 - agl1;
			return agl;
		}
		/**判断直线AB是否与直线CD相交*/    
		public static lineIntersectSide(ax :number,ay :number,bx :number,by :number,cx :number,cy :number,dx :number,dy :number):Boolean    
		{    
			// A(x1, y1), B(x2, y2)的直线方程为：    
			// f(x, y) =  (y - y1) * (x1 - x2) - (x - x1) * (y1 - y2) = 0    
			
			var fC :number = (cy - ay) * (ax - bx) - (cx - ax) * (ay - by);    
			var fD :number = (dy - ay) * (ax - bx) - (dx - ax) * (ay - by);    
			
			if(fC * fD > 0)    
				return false;    
			
			return true;    
		}
		/**检测点是否在图形内*/
		public static isPointInShape(tX :number,tY :number,arr:Array<any>):boolean
		{
			let i:number,j:number;
			let len:number;	
			let oddNodes:boolean=false;
			len = arr.length;
			if(len < 6)return false;				
			j = len - 2;
			for (i=0;i < len; i+=2)
			{
				// if(arr[i+1]<tY && arr[j+1]>=tY || arr[j+1]<tY&& arr[i+1]>=tY)
				// {
				// 	if(arr[i]+(tY-arr[i+1])/(arr[j+1]-arr[i+1])*(arr[j]-arr[i])<tX)
				// 	{
				// 		oddNodes=!oddNodes;
				// 	}
				// }				
				if ((arr[i+1] > tY) != (arr[j+1] > tY) &&  (tX < (arr[j] - arr[i]) * (tY - arr[i+1]) / (arr[j+1] - arr[i+1]) + arr[i]))
                {
                    oddNodes = !oddNodes;
                }
				j=i;
			}
			return oddNodes;
		}		
		/**判断两条线段是否相交*/    
		public static intersect(ax :number,ay :number,bx :number,by :number,cx :number,cy :number,dx :number,dy :number):Boolean  
		{
			if(ay == by && ay == cy && cy == dy)
			{
				return (cx - ax) * (cx - bx) < 0 || (dx - ax) * (dx - bx) < 0
			}
			else if(ax == bx && ax == cx && cx == dx)
			{
				return (cy - ay) * (cy - by) < 0 || (dy - ay) * (dy - by) < 0
			}
			else
			{
				if(!PositionUtil.lineIntersectSide(ax,ay,bx,by,cx,cy,dx,dy))    
					return false;    
				if(!PositionUtil.lineIntersectSide(cx,cy,dx,dy,ax,ay,bx,by))    
					return false;
			}
			return true;    
		} 
		/**转换坐标
		 * @param toX 坐标X
		 * @param toY 坐标Y
		 * @param fromTarget 当前坐标的坐标系
		 * @param toTarget 目标坐标的坐标系，为null则只转到全局坐标
		 * */
		public static convertPos(toX :number,toY :number,fromTarget:egret.DisplayObject, toTarget:egret.DisplayObject=null):egret.Point
		{
			var pt:egret.Point;
			PositionUtil._pt.x = toX;
			PositionUtil._pt.y = toY;
			pt = fromTarget.localToGlobal(PositionUtil._pt.x,PositionUtil._pt.y);
			pt = toTarget?toTarget.globalToLocal(pt.x,pt.y):pt;
			return pt;
		}
		/**计算两点连线的线角度（弧度，正负pi）
		 * @param aX 终点x
		 * @param aY 终点y
		 * @param aX 起点x
		 * @param aY 起点y
		 * */
		public static calculateAngle(aX :number,aY :number,bX :number,bY :number) :number
		{
			if(aX == bX)
			{
				if(aY == bY)return 0;
				return (bY > aY ? -MathConst.HALF_PI:MathConst.HALF_PI);
			}
			return Math.atan2(aY - bY,aX - bX);
		}
		/**计算两点间的距离的平方*/
		public static calculateDistance2(aX :number,aY :number,bX :number,bY :number) :number
		{
			var d1 :number,d2 :number;
			d1 = bY - aY;
			d2 = bX - aX;
			return d1 * d1 + d2 * d2;
		}
		/**计算两点间的距离*/
		public static calculateDistance(aX :number,aY :number,bX :number,bY :number) :number
		{
			var d1 :number,d2 :number;
			d1 = bY - aY;
			d2 = bX - aX;
			return Math.sqrt(d1 * d1 + d2 * d2);
		}
		public static vectorToArray(vec:Array<Number>):Array<any>
		{
			var i :number,len :number;
			var arr:Array<any>=[];
			len = vec.length;
			for(i=0;i<len;++i)
			{
				arr.push(vec[i]);
			}
			return arr;
		}
		public static vectorToIntArray(vec:Array<number>):Array<any>
		{
			var i :number,len :number;
			var arr:Array<any>=[];
			len = vec.length;
			for(i=0;i<len;++i)
			{
				arr.push((vec[i]>>0));
			}
			return arr;
		}
		public static vectorToCeilArray(vec:Array<number>):Array<any>
		{
			var i :number,len :number;
			var arr:Array<any>=[];
			len = vec.length;
			for(i=0;i<len;++i)
			{
				arr.push(Math.ceil((vec[i])));
			}
			return arr;
		}
		
		public static copyNumberVector(sVec:Array<any>,vec:Array<any>):void
		{
			var len :number;
			sVec.length = vec.length;
			len = sVec.length;
			while(--len>-1)
			{
				sVec[len] = vec[len];
			}
		}
		
		public static rectExtendRight(sArr:Object,extendPixels:number = 1):void
		{
			var agl :number;
			agl = PositionUtil.calculateAngle(sArr[2],sArr[3],sArr[0],sArr[1]);
			sArr[2] += Math.cos(agl) * extendPixels;
			sArr[3] += Math.sin(agl) * extendPixels;
			
			agl = PositionUtil.calculateAngle(sArr[4],sArr[5],sArr[6],sArr[7]);
			sArr[4] += Math.cos(agl) * extendPixels;
			sArr[5] += Math.sin(agl) * extendPixels;
		}
		
		public static rectExtendBottom(sArr:Object,extendPixels :number = 1):void
		{
			var agl :number;
			agl = PositionUtil.calculateAngle(sArr[4],sArr[5],sArr[2],sArr[3]);
			sArr[4] += Math.cos(agl) * extendPixels;
			sArr[5] += Math.sin(agl) * extendPixels;
			
			agl = PositionUtil.calculateAngle(sArr[6],sArr[7],sArr[0],sArr[1]);
			sArr[6] += Math.cos(agl) * extendPixels;
			sArr[7] += Math.sin(agl) * extendPixels;
		}
		/**排列对象函数
		 * @param IGYDisplay 数组
		 * @param pos 排列模式 0 顶部对齐 1 垂直居中 2 底部对齐 3 左部对齐 4 水平居中 5 右部对齐 6 水平等距 7 垂直等距
		 * */
		public static placeDisplay(arr:Array<any>, pos :number):void
		{
			var display:IGYDisplay;
			var maxLeft :number=0,maxRight :number=0,maxTop :number=0,maxBottom :number=0;
			var maxLeftDisplay:IGYDisplay,maxRightDisplay:IGYDisplay,maxTopDisplay:IGYDisplay,maxBottomDisplay:IGYDisplay;
			var i :number,len :number;
			var temp :number;
			var sortArr:Array<any>;
			var len2 :number;
			var startX :number,startY :number,endX :number,endY :number;
			if(arr ==null || arr.length < 1)return;
			if(pos < 0 || pos > 7)return;
			display = arr[0];
			maxLeft = display.x;
			maxTop = display.y;
			maxRight = maxLeft + display.width;
			maxBottom = maxTop + display.height;
			maxLeftDisplay = maxRightDisplay = maxTopDisplay = maxBottomDisplay = display;
			if(pos == 6 || pos == 7)
				sortArr = [];
			len = arr.length;
			for(i=0;i<len;++i)
			{
				display = arr[i];
				if(display.x < maxLeft)
				{
					maxLeft = display.x;
					maxLeftDisplay = display;
				}
				if(display.y < maxTop)
				{
					maxTop = display.y;
					maxTopDisplay = display;
				}
				temp = display.x + display.width;
				if(temp > maxRight)
				{
					maxRight = temp;
					maxRightDisplay = display;
				}
				temp = display.y + display.height;
				if(temp > maxBottom)
				{
					maxBottom = temp;
					maxBottomDisplay = display;
				}
				if(pos == 7)
				{
					if(maxTopDisplay == display)					
						sortArr.unshift(display);						
					else if(maxBottomDisplay == display)					
						sortArr.push(display);						
					else
					{
						len2 = sortArr.length;
						while(--len2>-1)
						{
							if(sortArr[len2].y < display.y || sortArr[len2].y == display.y && sortArr[len2].x < display.x)
							{
								sortArr.splice(len2 + 1, 0, display);
								break;
							}
						}
					}
				}
				else if(pos == 6)
				{
					if(maxLeftDisplay == display)
						sortArr.unshift(display);
					else if(maxRightDisplay == display)					
						sortArr.push(display);
					else
					{
						len2 = sortArr.length;
						while(--len2>-1)
						{
							if(sortArr[len2].x < display.x || sortArr[len2].x == display.x && sortArr[len2].y < display.y)
							{
								sortArr.splice(len2 + 1, 0, display);
								break;
							}
						}
					}
				}
			}			
			if(pos == 0)//顶部对齐
			{
				len = arr.length;
				while(--len > -1)
					arr[len].y = maxTop;
			}
			else if(pos == 1)//垂直对齐
			{
				len = arr.length;
				while(--len > -1)
				{
					display = arr[len];
					display.y = maxTop + (maxBottom - maxTop - display.height >> 1);
				}					
			}
			else if(pos == 2)//底部对齐
			{
				len = arr.length;
				while(--len > -1)
				{
					display = arr[len];
					display.y = maxBottom - display.height;
				}
			}
			else if(pos == 3)//左部对齐
			{
				len = arr.length;
				while(--len > -1)
					arr[len].x = maxLeft;
			}
			else if(pos == 4)//水平对齐
			{
				len = arr.length;
				while(--len > -1)
				{
					display = arr[len];
					display.x = maxLeft + (maxRight - maxLeft - display.width >> 1);
				}
			}
			else if(pos == 5)//右部对齐
			{
				len = arr.length;
				while(--len > -1)
				{
					display = arr[len];
					display.x = maxRight - display.width;
				}
			}
			else if(pos == 6)//水平等距排列
			{
				len = sortArr.length - 1;
				maxLeft = sortArr[0].x;
				maxRight = sortArr[len].x + sortArr[len].width;
				startX = maxLeft + (sortArr[0].width >> 1);
				endX = maxRight - (sortArr[sortArr.length - 1].width >> 1);				
				temp = (endX - startX) / len;				
				for(i=1;i<len;++i)
				{
					display = arr[i];
					display.x = startX + temp * i - (display.width >> 1);
				}
			}
			else if(pos == 7)//垂直等距排列
			{
				len = sortArr.length - 1;
				maxTop = sortArr[0].y;
				maxBottom = sortArr[len].y + sortArr[len].height;
				startY = maxTop + (sortArr[0].height >> 1);
				endY = maxBottom - (sortArr[len].height >> 1);				
				temp = (endY - startY) / len;
				for(i=1;i<len;++i)
				{
					display = arr[i];
					display.y = startY + temp * i - (display.height >> 1);
				}
			}
		}
	}
}